package util;

/**
 * This is a utility class for "Array-Strings", strings represented as just arrays to save memory and avoid immutability.
 * NOTE: Although I'm normally not up for abreviations of names, "ArrayStringUtil" is just to long to justify for something like this.
 * @author Neil Dickson
 */
public final class ASUtil {
	public static boolean equals(byte[] a,Object b) {
		return (a==b) || (b instanceof byte[] && equals(a,(byte[])b)) || (b instanceof String && equals(a,(String)b));
	}

	public static boolean equals(byte[] a,byte[] b) {
		if (a.length!=b.length) {
			return false;
		}
		for (int i=0;i<a.length;++i) {
			if (a[i]!=b[i]) {
				return false;
			}
		}
		return true;
	}

	public static boolean equals(byte[] a,String b) {
		if (a.length!=b.length()) {
			return false;
		}
		for (int i=0;i<a.length;++i) {
			if (a[i]!=b.charAt(i)) {
				return false;
			}
		}
		return true;
	}

	public static boolean equalsAt(byte[] a,byte[] b) {
		if (a.length!=b.length) {
			return false;
		}
		for (int i=0;i<a.length;++i) {
			if (a[i]!=b[i]) {
				return false;
			}
		}
		return true;
	}

	public static boolean equalsAt(byte[] a,String b) {
		if (a.length!=b.length()) {
			return false;
		}
		for (int i=0;i<a.length;++i) {
			if (a[i]!=b.charAt(i)) {
				return false;
			}
		}
		return true;
	}


	public static int indexOf(byte[] text, char c, int index) {
		while (index<text.length && text[index]!=c) {
			++index;
		}
		return (index==text.length)?-1:index;
	}

	public static int indexOf(char[] text, char c, int index) {
		while (index<text.length && text[index]!=c) {
			++index;
		}
		return (index==text.length)?-1:index;
	}

	public static char[] subCharArray(byte[] text, int start, int end) {
		char[] a = new char[end-start];
		int i=0;
		while (start+i<end) {
			a[i] = (char)text[start+i];
			i++;
		}
		return a;
	}

	public static String substring(byte[] text, int start, int end) {
		return new String(text,start,end-start);
	}

	public static char[] subCharArray(char[] text,int start,int end) {
		char[] newText = new char[end-start];
		System.arraycopy(text,start,newText,0,end-start);
		return newText;
	}

	public static int getTokenStart(char[] text,int i,char[] extra) {
		char c = text[i];
		char c2 = (char)(c|0x20);
		// If the starting character is a word character, scan until the first non-word character.
		if ((c2>='a' && c2<='z') || (c>='0' && c<='9') || (extra!=null && indexOf(extra,c,0)>=0)) {
			while (i>0) {
				c = text[i-1];
				c2 = (char)(c|0x20);
				if ((c2<'a' || c2>'z') && (c<'0' || c>'9') && (extra==null || indexOf(extra,c,0)<0)) {
					return i;
				}
				--i;
			}
			return 0;
		}
		// If the starting character is a whitespace character, scan until the first non-whitespace character.
		else if (c<=' ') {
			while (i>0) {
				if (text[i-1]>' ') {
					return i;
				}
				--i;
			}
			return 0;
		}
		// Otherwise (e.g. an operator character), return the original index as the start.
		return i;
	}

	public static int getTokenEnd(char[] text,int i,char[] extra) {
		char c = text[i];
		char c2 = (char)(c|0x20);
		// Move to the next character (since end is always at least one character after the first)
		++i;
		// If the starting character is a word character, scan until the first non-word character.
		if ((c2>='a' && c2<='z') || (c>='0' && c<='9') || (extra!=null && indexOf(extra,c,0)>=0)) {
			while (i<text.length) {
				c = text[i];
				c2 = (char)(c|0x20);
				if ((c2<'a' || c2>'z') && (c<'0' || c>'9') && (extra==null || indexOf(extra,c,0)<0)) {
					return i;
				}
				++i;
			}
			return i;
		}
		// If the starting character is a whitespace character, scan until the first non-whitespace character.
		else if (c<=' ') {
			while (i<text.length && text[i]<=' ') {
				++i;
			}
			return i;
		}
		// Otherwise (e.g. an operator character), return the index following the original index as the end.
		return i;
	}

	public static boolean equals(char[] a, char[] b, int length) {
		for (int i=0;i<length;++i) {
			if (a[i]!=b[i]) {
				return false;
			}
		}
		return true;
	}
}
